﻿using System.Collections.Generic;

namespace smp.QueryDb
{
    public interface IFilterOperator<TViewModel>
    {
        Filter<TViewModel> EqualTo(object value);
        Filter<TViewModel> GreaterThan(object value);
        Filter<TViewModel> GreaterThanOrEqualTo(object value);
        Filter<TViewModel> LessThan(object value);
        Filter<TViewModel> LessThanOrEqualTo(object value);
        Filter<TViewModel> Contains(object value);
        Filter<TViewModel> StartsWith(object value);
        Filter<TViewModel> EndsWith(object value);
        Filter<TViewModel> In(IList<object> values);
        Filter<TViewModel> Null { get; }
    }

    internal class FilterOperator<TViewModel> : IFilterOperator<TViewModel>
    {
        private readonly Filter<TViewModel> _filter;
        private readonly bool _isNot;

        internal FilterOperator(Filter<TViewModel> filter, bool isNot)
        {
            _filter = filter;
            _isNot = isNot;
        }

        public Filter<TViewModel> EqualTo(object value)
        {
            _filter.Structure.SetOperation(_isNot ? "!=" : "=", value);
            return _filter;
        }

        public Filter<TViewModel> GreaterThan(object value)
        {
            _filter.Structure.SetOperation(_isNot ? "<=" : ">", value);
            return _filter;
        }

        public Filter<TViewModel> GreaterThanOrEqualTo(object value)
        {
            _filter.Structure.SetOperation(_isNot ? "<" : ">=", value);
            return _filter;
        }

        public Filter<TViewModel> LessThan(object value)
        {
            _filter.Structure.SetOperation(_isNot ? ">=" : "<", value);
            return _filter;
        }

        public Filter<TViewModel> LessThanOrEqualTo(object value)
        {
            _filter.Structure.SetOperation(_isNot ? ">" : "<=", value);
            return _filter;
        }

        public Filter<TViewModel> Contains(object value)
        {
            _filter.Structure.SetStringOperation(FilterStructure.StringComparitor.Contains, value);
            return _filter;
        }

        public Filter<TViewModel> StartsWith(object value)
        {
            _filter.Structure.SetStringOperation(FilterStructure.StringComparitor.StartsWith, value);
            return _filter;
        }

        public Filter<TViewModel> EndsWith(object value)
        {
            _filter.Structure.SetStringOperation(FilterStructure.StringComparitor.EndsWith, value);
            return _filter;
        }

        public Filter<TViewModel> In(IList<object> values)
        {
            _filter.Structure.SetInOperation(values);
            return _filter;
        }

        public Filter<TViewModel> Null
        {
            get
            {
                _filter.Structure.SetOperation(_isNot ? "IS NOT NULL" : "IS NULL", null);
                return _filter;
            }
        }
    }
}
